<?php

namespace app\api\service;

use app\api\model\BaseModel;
use app\lib\enum\UserScope;
use app\lib\exception\NoPermissionException;
use app\lib\exception\TokenMissException;
use think\Cache;
use think\Exception;
use think\Request;

class Token extends BaseModel
{

    /**
     * 获取 token, 32 位长度
     * @return string
     */
    public static function generateToken()
    {
        $token     = getRandChar(32);
        $timestamp = $_SERVER['REQUEST_TIME_FLOAT'];
        $salt      = config('secure.salt');

        return md5($token.$timestamp.$salt);
    }

    public static function getValByToken($key)
    {
        $token = Request::instance()->header('token');
        if ( !$token) throw new TokenMissException(['msg' => '没有从请求头中获取到 Token']);

        $cacheVal = Cache::get($token);
        if ( !$cacheVal) throw new TokenMissException();

        if ( !is_array($cacheVal)) $cacheVal = json_decode($cacheVal, true);
        if ( !array_key_exists($key, $cacheVal)) throw new Exception('查找的键在缓存中不存在');

        return $cacheVal[$key];
    }

    /**
     * 根据token获取UID
     * @return mixed
     * @throws Exception
     * @throws TokenMissException
     */
    public static function getUidByToken()
    {
        $uid = self::getValByToken('uid');
        return $uid;
    }

    /**
     * 校验用户权限, 必须要有 >= 用户权限才能访问
     * @return bool
     * @throws Exception
     * @throws NoPermissionException
     * @throws TokenMissException
     */
    public static function needUserScope()
    {
        $scope = self::getValByToken('scope');
        if ( !$scope) throw new TokenMissException();

        if ( $scope < UserScope::USER) throw new NoPermissionException();

        return true;
    }

    /**
     * 只有用户权限才能访问, CMS 权限不能访问
     * @return bool
     * @throws Exception
     * @throws NoPermissionException
     * @throws TokenMissException
     */
    public static function needExclusiveUserScope()
    {
        $scope = self::getValByToken('scope');
        if ( !$scope) throw new TokenMissException();

        if ( $scope != UserScope::USER) throw new NoPermissionException();

        return true;
    }
}